<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1.webGL绘制几何图形--三角形</title>
</head>
<body>
    <canvas width="300" height="300"></canvas>

    <script>
        /**
         * 1. 创建 WebGL 上下文
         * 2. 创建 WebGL 程序（WebGL Program）
         * 3. 将数据存入缓冲区
         * 4. 将缓冲区数据读取到 GPU
         * 5. GPU 执行 WebGL 程序，输出结果
        */

        const canvas = document.querySelector("canvas")
        const gl = canvas.getContext("webgl")

        const vertex = ` 
            attribute vec2 position; 
            void main() { 
                gl_PointSize = 1.0; 
                gl_Position = vec4(position, 1.0, 1.0); 
            }
        `;
        const fragment = ` 

            #ifdef GL_ES
            precision mediump float;
            #endif

            #define PI 3.14159265359

            uniform vec2 u_resolution;
            uniform vec2 u_mouse;
            uniform float u_time;

            float plot(vec2 st, float pct){
            return  smoothstep( pct-0.02, pct, st.y) -
                    smoothstep( pct, pct+0.02, st.y);
            }

            void main() {
                vec2 st = gl_FragCoord.xy/u_resolution;

                float y = pow(st.x,3.0);

                vec3 color = vec3(y);

                float pct = plot(st,y);
                color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0);

                gl_FragColor = vec4(color,1.0);
            }
        `;

        // 创建顶点着色器对象
        const vertexShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertexShader, vertex);
        gl.compileShader(vertexShader);

        // 创建片元着色器对象
        const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragmentShader, fragment);
        gl.compileShader(fragmentShader);

        // 2. 创建 WebGLProgram 对象
        const program = gl.createProgram();
        // 添加 vertexShader 和 fragmentShader
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);

        // 将这个 WebGLProgram 对象链接到 WebGL 上下文对象上
        gl.linkProgram(program);

        // 通过 useProgram 选择启用这个 WebGLProgram 对象，这样，当我们绘制图形时，GPU 就会执行我们通过 WebGLProgram 设定的 两个 shader 程序了。
        gl.useProgram(program);

        /** 创建三角形 */ 

        // 3. 将数据存入缓冲区
        // 定义类型化数组
        const points = new Float32Array([ -1, -1, 0, 1, 1, -1,]);
        // createBuffer
        const bufferId = gl.createBuffer();
        // bindBuffer
        gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
        // bufferData
        gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);

        // 4. 将缓冲区数据读取到 GPU
        // 把数据绑定给顶点着色器中的 position 变量。
        // 获取顶点着色器中的position变量的地址
        const vPosition = gl.getAttribLocation(program, 'position');
        // 给变量设置长度和类型
        gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
        // 激活这个变量
        gl.enableVertexAttribArray(vPosition);


        // 设置 uniform 变量
        function setUniforms(gl, { u_time }) {
            loc = gl.getUniformLocation(program, 'u_time');
            gl.uniform1f(loc, u_time);
        }

        

        // 根据时间更新像素
        function update(ltime){
            // 5. 执行着色器程序完成绘制
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.TRIANGLES, 0, points.length / 2); // 实心三角形

        }
        update(performance.now())

    </script>
</body>
</html>